use serde::{Deserializer, Serialize, Serializer};
use spin::RwLock;
use std::cell::UnsafeCell;
use std::fmt::{Debug, Formatter, Pointer};
use std::ops::{Deref, DerefMut, Index};
use std::slice::{Iter as SliceIter, IterMut as SliceIterMut};
use std::sync::Arc;
use std::vec::IntoIter;

pub struct SyncVec<V> {
    dirty: UnsafeCell<Vec<V>>,
    lock: RwLock<()>,
}

/// this is safety, dirty mutex ensure
unsafe impl<V> Send for SyncVec<V> {}

/// this is safety, dirty mutex ensure
unsafe impl<V> Sync for SyncVec<V> {}

impl<V> Default for SyncVec<V> {
    fn default() -> Self {
        Self::new()
    }
}

impl<V> From<Vec<V>> for SyncVec<V> {
    fn from(v: Vec<V>) -> Self {
        Self::with_vec(v)
    }
}

impl<V> SyncVec<V>
where
    V: Clone,
{
    pub fn to_vec(&self) -> Vec<V> {
        let mut v = Vec::new();
        for i in self.iter() {
            v.push(i.clone());
        }
        v
    }
}

impl<V> SyncVec<V> {
    pub fn new_arc() -> Arc<Self> {
        Arc::new(Self::new())
    }

    pub const fn new() -> Self {
        Self {
            dirty: UnsafeCell::new(Vec::new()),
            lock: RwLock::new(()),
        }
    }

    pub const fn with_vec(vec: Vec<V>) -> Self {
        Self {
            dirty: UnsafeCell::new(vec),
            lock: RwLock::new(()),
        }
    }

    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            dirty: UnsafeCell::new(Vec::with_capacity(capacity)),
            lock: RwLock::new(()),
        }
    }

    #[inline(always)]
    fn as_arr(&self) -> &Vec<V> {
        unsafe { &*self.dirty.get() }
    }

    #[inline(always)]
    fn as_arr_mut(&self) -> &mut Vec<V> {
        unsafe { &mut *self.dirty.get() }
    }

    #[inline(always)]
    pub fn insert(&self, index: usize, v: V) {
        let _lock = self.lock.write();
        self.as_arr_mut().insert(index, v);
    }

    #[inline(always)]
    pub fn push(&self, v: V) {
        let _lock = self.lock.write();
        self.as_arr_mut().push(v);
    }

    #[inline(always)]
    pub fn push_return(&self, v: V) -> usize {
        let _lock = self.lock.write();
        let u = self.as_arr_mut();
        let index = u.len();
        u.push(v);
        index
    }

    #[inline(always)]
    pub fn push_vec(&self, input_arr: Vec<V>) {
        let mut _lock = self.lock.write();
        let u = self.as_arr_mut();
        for ele in input_arr.into_iter() {
            u.push(ele);
        }
    }

    pub fn pop(&self) -> Option<V> {
        let _lock = self.lock.write();
        let u = self.as_arr_mut();
        let r = u.pop();
        r
    }

    pub fn remove(&self, index: usize) -> Option<V> {
        let _lock = self.lock.write();
        let u = self.as_arr_mut();
        if u.len() > index {
            let v = u.remove(index);
            Some(v)
        } else {
            None
        }
    }

    pub fn len(&self) -> usize {
        let _lock = self.lock.read();
        let u = self.as_arr();
        u.len()
    }

    pub fn is_empty(&self) -> bool {
        let _lock = self.lock.read();
        let u = self.as_arr();
        u.is_empty()
    }

    pub fn clear(&self) {
        let _lock = self.lock.write();
        let u = self.as_arr_mut();
        u.clear();
    }

    pub fn shrink_to_fit(&self) {
        let _lock = self.lock.write();
        let u = self.as_arr_mut();
        u.shrink_to_fit();
    }

    pub const fn from(vec: Vec<V>) -> Self {
        let s = Self::with_vec(vec);
        s
    }

    #[inline]
    pub fn get(&self, index: usize) -> Option<ReadGuard<'_, V>> {
        let _lock = self.lock.read();
        let u = self.as_arr();
        if u.get(index).is_none() {
            None
        } else {
            Some(ReadGuard {
                _lock,
                v: &u[index],
            })
        }
    }

    #[inline]
    pub fn get_uncheck(&self, index: usize) -> ReadGuard<'_, V> {
        let _lock = self.lock.read();
        let u = self.as_arr();
        ReadGuard {
            _lock,
            v: &u[index],
        }
    }

    #[inline]
    pub fn get_mut(&self, index: usize) -> Option<WriteGuard<'_, V>> {
        let _lock = self.lock.write();
        let u = self.as_arr_mut();
        if u.get(index).is_none() {
            return None;
        }
        Some(WriteGuard {
            _lock,
            v: &mut u[index],
        })
    }

    #[inline]
    pub fn contains(&self, x: &V) -> bool
    where
        V: PartialEq,
    {
        let _lock = self.lock.read();
        let u = self.as_arr();
        u.contains(x)
    }

    pub fn iter(&self) -> Iter<'_, V> {
        let _lock = self.lock.read();
        let u = self.as_arr();
        Iter {
            _lock: Some(_lock),
            lock_arc: None,
            inner: u.iter(),
        }
    }

    pub fn iter_mut<'a>(&'a self) -> IterMut<'a, V> {
        let mut _lock: spin::rwlock::RwLockWriteGuard<'_, ()> = self.lock.write();
        let iter = self.as_arr_mut().iter_mut();
        let iter = IterMut { _lock, inner: iter };
        return iter;
    }

    pub fn into_iter(self) -> IntoIter<V> {
        let _lock = self.lock.write();
        let m = self.dirty.into_inner();
        m.into_iter()
    }

    pub fn dirty_ref(&self) -> ReadGuardVec<V> {
        ReadGuardVec {
            _lock: self.lock.read(),
            v: self.as_arr(),
        }
    }

    pub fn into_inner(self) -> Vec<V> {
        self.dirty.into_inner()
    }
}

pub struct ReadGuard<'a, V> {
    _lock: spin::RwLockReadGuard<'a, ()>,
    v: &'a V,
}

impl<'a, V> Deref for ReadGuard<'a, V> {
    type Target = V;
    fn deref(&self) -> &Self::Target {
        self.v
    }
}

impl<'a, V> Debug for ReadGuard<'_, V>
where
    V: Debug,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.v)
    }
}

// impl display for ReadGuard
impl<'a, V> std::fmt::Display for ReadGuard<'_, V>
where
    V: std::fmt::Display,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.v.fmt(f)
    }
}

// impl as_ref for ReadGuard
impl<'a, V> AsRef<V> for ReadGuard<'a, V> {
    fn as_ref(&self) -> &V {
        self.v
    }
}

pub struct ReadGuardVec<'a, V> {
    _lock: spin::RwLockReadGuard<'a, ()>,
    v: &'a Vec<V>,
}

impl<'a, V> Deref for ReadGuardVec<'a, V> {
    type Target = Vec<V>;
    fn deref(&self) -> &Self::Target {
        self.v
    }
}

// impl as_ref for ReadGuardVec
impl<'a, V> AsRef<Vec<V>> for ReadGuardVec<'a, V> {
    fn as_ref(&self) -> &Vec<V> {
        self.v
    }
}

// impl debug for ReadGuardVec
impl<'a, V> Debug for ReadGuardVec<'_, V>
where
    V: Debug,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.v)
    }
}

// impl display for ReadGuardVec
impl<'a, V> std::fmt::Display for ReadGuardVec<'_, V>
where
    V: std::fmt::Display,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.v.fmt(f)
    }
}

pub struct WriteGuard<'a, V> {
    _lock: spin::RwLockWriteGuard<'a, ()>,
    v: &'a mut V,
}

// as_ref for WriteGuard
impl<'a, V> AsRef<V> for WriteGuard<'a, V> {
    fn as_ref(&self) -> &V {
        self.v
    }
}

// as_mut for WriteGuard
impl<'a, V> AsMut<V> for WriteGuard<'a, V> {
    fn as_mut(&mut self) -> &mut V {
        self.v
    }
}

impl<'a, V> Deref for WriteGuard<'_, V> {
    type Target = V;

    fn deref(&self) -> &Self::Target {
        self.v
    }
}

impl<'a, V> DerefMut for WriteGuard<'_, V> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.v
    }
}

impl<'a, V> Debug for WriteGuard<'_, V>
where
    V: Debug,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.v)
    }
}

// impl display for WriteGuard
impl<'a, V> std::fmt::Display for WriteGuard<'_, V> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.v.fmt(f)
    }
}

pub struct Iter<'a, V> {
    _lock: Option<spin::RwLockReadGuard<'a, ()>>,
    lock_arc: Option<Arc<spin::RwLockReadGuard<'a, ()>>>,
    inner: SliceIter<'a, V>,
}

impl<'a, V> Iter<'a, V> {
    pub fn clone_lock(&mut self) -> Arc<spin::RwLockReadGuard<'a, ()>> {
        if self._lock.is_some() {
            let lock = self._lock.take().expect("lock is None");
            let lock = Arc::new(lock);
            self.lock_arc = Some(lock.clone());
            lock
        } else {
            self.lock_arc.as_ref().expect("lock_arc is None").clone()
        }
    }
}

impl<'a, V> Iterator for Iter<'a, V> {
    type Item = &'a V;
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}

pub struct IterMut<'a, V> {
    _lock: spin::rwlock::RwLockWriteGuard<'a, ()>,
    inner: SliceIterMut<'a, V>,
}

impl<'a, V> Deref for IterMut<'a, V> {
    type Target = SliceIterMut<'a, V>;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl<'a, V> DerefMut for IterMut<'a, V> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.inner
    }
}

impl<'a, V> Iterator for IterMut<'a, V> {
    type Item = &'a mut V;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}

impl<'a, V> IntoIterator for &'a SyncVec<V> {
    type Item = &'a V;
    type IntoIter = Iter<'a, V>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<V> IntoIterator for SyncVec<V> {
    type Item = V;
    type IntoIter = IntoIter<V>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_iter()
    }
}

impl<V> Serialize for SyncVec<V>
where
    V: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        self.dirty_ref().serialize(serializer)
    }
}

impl<'de, V> serde::Deserialize<'de> for SyncVec<V>
where
    V: serde::Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let m = Vec::deserialize(deserializer)?;
        Ok(Self::from(m))
    }
}

impl<V> Debug for SyncVec<V>
where
    V: Debug,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.dirty_ref())
    }
}

// impl display for SyncVec
impl<V: std::fmt::Display> std::fmt::Display for SyncVec<V> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.dirty_ref())
    }
}

/// this function is unsafe, plase checking the vec not write data
impl<V> Index<usize> for SyncVec<V> {
    type Output = V;
    fn index(&self, index: usize) -> &Self::Output {
        &self.as_arr()[index]
    }
}

impl<V: PartialEq> PartialEq for SyncVec<V> {
    fn eq(&self, other: &Self) -> bool {
        self.dirty_ref().eq(other.dirty_ref().as_ref())
    }
}

impl<V: Clone> Clone for SyncVec<V> {
    fn clone(&self) -> Self {
        SyncVec::from(self.dirty_ref().to_vec())
    }
}

#[macro_export]
macro_rules! sync_vec {
    () => (
        $crate::sync::SyncVec::new()
    );
    ($elem:expr; $n:expr) => (
        $crate::sync::SyncVec::with_vec(vec![$elem;$n])
    );
    ($($x:expr),+ $(,)?) => (
        $crate::sync::SyncVec::with_vec(vec![$($x),+,])
    );
}

#[test]
fn test_case() {
    struct D {}
    impl D {
        fn is_some(&self) -> bool {
            println!("is_some");
            true
        }
        fn take(&mut self) -> Option<bool> {
            println!("take");
            Some(true)
        }
    }

    let mut d = D {};
    if let (true, Some(d)) = (d.is_some(), d.take()) {
        println!("d is {d}");
    }
}
